#include "HPTools.h"



QDataStream &operator<<(QDataStream &out, const PenInfo &penInfo)
{
    out << (int)(penInfo.type);
    out << penInfo.size;
    out << penInfo.color;
    return out;
}

QDataStream& operator >>( QDataStream &in, PenInfo& penInfo )
{
    int i;
    in >> i;
    penInfo.type = (PenType)i;
    in >> penInfo.size;
    in >> penInfo.color;

    return in;
}



bool unzip(const QString & filePath, const QString & extDirPath, const QString & singleFileName)
{
    QuaZip zip(filePath);

    if (!zip.open(QuaZip::mdUnzip))
    {
        qWarning("testRead(): zip.open(): %d", zip.getZipError());
        return false;
    }

    zip.setFileNameCodec("IBM866");

    qWarning("%d entries\n", zip.getEntriesCount());
    qWarning("Global comment: %s\n", zip.getComment().toLocal8Bit().constData());

    QuaZipFileInfo info;
    QuaZipFile file(&zip);

    QFile out;
    QString name;
    char c;
    for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
    {
        if (!zip.getCurrentFileInfo(&info))
        {
            qWarning("testRead(): getCurrentFileInfo(): %d\n", zip.getZipError());
            return false;
        }

        if (!singleFileName.isEmpty())
        {
            if (!info.name.contains(singleFileName))
            {
                continue;
            }
        }

        if (!file.open(QIODevice::ReadOnly))
        {
            qWarning("testRead(): file.open(): %d", file.getZipError());
            return false;
        }

        name = QString("%1/%2").arg(extDirPath).arg(file.getActualFileName());

        if (file.getZipError() != UNZ_OK)
        {
            qWarning("testRead(): file.getFileName(): %d", file.getZipError());
            return false;
        }

        //out.setFileName("out/" + name);
        out.setFileName(name);

        // this will fail if "name" contains subdirectories, but we don't mind that
        out.open(QIODevice::WriteOnly);
        // Slow like hell (on GNU/Linux at least), but it is not my fault.
        // Not ZIP/UNZIP package's fault either.
        // The slowest thing here is out.putChar(c).
        while (file.getChar(&c)) out.putChar(c);

        out.close();

        if (file.getZipError() != UNZ_OK)
        {
            qWarning("testRead(): file.getFileName(): %d", file.getZipError());
            return false;
        }

        if (!file.atEnd())
        {
            qWarning("testRead(): read all but not EOF");
            return false;
        }

        file.close();

        if (file.getZipError() != UNZ_OK)
        {
            qWarning("testRead(): file.close(): %d", file.getZipError());
            return false;
        }
    }

    zip.close();

    if (zip.getZipError() != UNZ_OK)
    {
        qWarning("testRead(): zip.close(): %d", zip.getZipError());
        return false;
    }

    return true;
}

bool zip(const QString & filePath, const QDir & dir, const QString & comment)
{
    QuaZip zip(filePath);
    zip.setFileNameCodec("IBM866");

    HP_AUTOLOG();

    if (!zip.open(QuaZip::mdCreate))
    {
        //myMessageOutput(true, QtDebugMsg, QString("testCreate(): zip.open(): %1").arg(zip.getZipError()));
        HP_AUTOLOG();
        return false;
    }

    if (!dir.exists())
    {
        //myMessageOutput(true, QtDebugMsg, QString("dir.exists(%1)=FALSE").arg(dir.absolutePath()));
        HP_AUTOLOG();
        return false;
    }

    QFile inFile;
    //add 1 level files //TODO add recursive
    QFileInfoList files = QDir(dir).entryInfoList();

    QuaZipFile outFile(&zip);

    char c;
    foreach(QFileInfo fileInfo, files)
    {
        if (!fileInfo.isFile())
        {
            continue;
        }

        QString fileNameWithRelativePath = fileInfo.filePath().remove(0, dir.absolutePath().length() + 1);

        inFile.setFileName(fileInfo.filePath());

        if (!inFile.open(QIODevice::ReadOnly))
        {
            //myMessageOutput(true, QtDebugMsg, QString("testCreate(): inFile.open(): %1").arg(inFile.errorString().toLocal8Bit().constData()));
            HP_AUTOLOG();
            return false;
        }

        if (!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileNameWithRelativePath, fileInfo.filePath())))
        {
            //        myMessageOutput(true, QtDebugMsg, QString("testCreate(): outFile.open(): %1").arg(outFile.getZipError()));
            HP_AUTOLOG();
            return false;
        }

        while (inFile.getChar(&c) && outFile.putChar(c));

        if (outFile.getZipError() != UNZ_OK)
        {
            //myMessageOutput(true, QtDebugMsg, QString("testCreate(): outFile.putChar(): %1").arg(outFile.getZipError()));
            HP_AUTOLOG();
            return false;
        }

        outFile.close();

        if (outFile.getZipError() != UNZ_OK)
        {
            //myMessageOutput(true, QtDebugMsg, QString("testCreate(): outFile.close(): %1").arg(outFile.getZipError()));
            HP_AUTOLOG();
            return false;
        }

        inFile.close();
    }

    if (!comment.isEmpty())
    {
        zip.setComment(comment);
    }

    zip.close();

    if (zip.getZipError() != 0)
    {
        //myMessageOutput(true, QtDebugMsg, QString("testCreate(): zip.close(): %1").arg(zip.getZipError()));
        HP_AUTOLOG();
        return false;
    }

    return true;
}




// Convert an image to grayscale and return it as a new image
QImage grayscaled(const QImage &image)
{
    QImage img = image;
    int pixels = img.width() * img.height();
    unsigned int *data = (unsigned int *)img.bits();
    for (int i = 0; i < pixels; ++i) {
        int val = qGray(data[i]);
        data[i] = qRgba(val, val, val, qAlpha(data[i]));
    }
    return img;
}
// Tint an image with the specified color and return it as a new image
QImage tinted(const QImage &image, const QColor &color)
{
    QImage resultImage(image.size(), QImage::Format_ARGB32_Premultiplied);
    QPainter painter(&resultImage);
    painter.fillRect(resultImage.rect(), color);

    painter.setCompositionMode(QPainter::CompositionMode_Multiply);
    painter.drawImage(0, 0, grayscaled(image));
    painter.end();

    resultImage.setAlphaChannel(image.alphaChannel());
    return resultImage;
}


void tint( QAbstractButton* _pButton, QColor _color )
{
    QPixmap pix = _pButton->icon().pixmap(200);
    _pButton->setIcon( QIcon(tinted(pix,_color)));
}

QPixmap tinted( const QPixmap& _rPixmap, QColor _color)
{
    QImage image = _rPixmap.toImage();

    QImage tintedImage = tinted(image, _color);

    return QPixmap::fromImage(tintedImage);
}

